package util;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.Projections;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Repository;

@Repository
public class HibernateBaseDao<T> implements BaseDao<T>{
	@Autowired
	protected HibernateTemplate hibernateTemplate;
	private Class<T> entityClass;
	{
		Type genType = getClass().getGenericSuperclass(); 
		Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); 
		entityClass =  (Class)params[0]; 

	}

	public PageVO<T> listByPage(T t, int page, int pageSize) {
		Example example = Example.create(t);
		example.enableLike().ignoreCase();
		DetachedCriteria criteria = DetachedCriteria.forClass(t.getClass());
		criteria.add(example);
		criteria.setProjection(Projections.rowCount());
		PageVO<T> pv = new PageVO<T>();
		pv.setTotalCount((Integer) hibernateTemplate.findByCriteria(criteria).get(0));
		criteria.setProjection(null);
		pv.setResultList(hibernateTemplate.findByCriteria(criteria, (page - 1) * pageSize, pageSize));
		return pv;
	}

	public PageVO<T> listByPage(DetachedCriteria criteria, int page, int pageSize) {
		PageVO<T> pv = new PageVO<T>();
		pv.setResultList( hibernateTemplate.findByCriteria(criteria, (page - 1) * pageSize, pageSize));
		criteria.setProjection(Projections.rowCount());
		pv.setTotalCount((Integer)hibernateTemplate.findByCriteria(criteria,0,1).get(0));
		return pv;
	}
	
	public List<T> find(String hql,Object ...paras){
		return hibernateTemplate.find(hql,paras);
	}

	public T getById(Serializable id){
		return hibernateTemplate.load(entityClass, id);
	}
	
	public List<T> listAll() throws Exception{
		return hibernateTemplate.findByExample(entityClass.newInstance());
	}
	
	public List<T> listAll(String orderBy) throws Exception{
		return hibernateTemplate.find("from "+entityClass.getSimpleName()+" order by "+orderBy);
	}
	
	public Serializable add(T t){
		return hibernateTemplate.save(t);
	}
	
	public boolean update(T t){
		try{
			hibernateTemplate.update(t);
			return true;
		}catch(Exception e){
			e.printStackTrace();
			return false;
		}
	}
	
	public boolean delete(T t){
		try{
			hibernateTemplate.delete(t);
			return true;
		}catch(Exception e){
			e.printStackTrace();
			return false;
		}
	}
}
